#include "XAudioThread.h"
#include "XDecode.h"
#include "XAudioPlay.h"
#include "XResample.h"
#include <qdebug.h>
bool XAudioThread::Open(AVCodecParameters * para ,int sampleRate, int channels)
{
	
	if (!para) {
		qDebug() << "XaudioThread::Open para is NULL";
		return false;
	}
	Clear();
	audiomux.lock();
	pts = 0;
	bool re = true;

	if (!(res->Open(para, false))) {
		qDebug() << "XResample open failed";
		re = false;
	}
	else {
		qDebug() << "XResample open success";
	}
	ap->sampleRate = sampleRate;
	ap->channels = channels;
	if (!ap->Open()) {
		re = false;
		qDebug() << "XAduioPlay open failed";
		//mux.unlock();
		//r/eturn false;
	}

	if (!(decode->Open(para))) {
		qDebug() << "audio XDecode open failed";
		re = false;
	}
	else {
		qDebug() << "audio XDecode open success";
	}

	audiomux.unlock();
	qDebug() << "XAudioThred::Open value = " << re;
	return re;
}

void XAudioThread::Close()
{
	XDecodeThread::Close();
	if (res) {
		res->Close();
		audiomux.lock();
		delete res;
		res = NULL;
		audiomux.unlock();
	}
	if (ap) {
		ap->Close();
		audiomux.lock();
		ap = NULL;
		audiomux.unlock();

	}
}

void XAudioThread::Clear()
{
	XDecodeThread::Clear();
	audiomux.lock();
	if (ap) {
		ap->Clear();
	}
	audiomux.unlock();
}

void XAudioThread::run()
{
	unsigned char *pcm = new unsigned char[1024 * 1024 * 10];
	while (!isExit) {
		if (Pause) {
			msleep(1);
			continue;
		}
		audiomux.lock();
		AVPacket *pkt = Pop();
		bool re = decode->Send(pkt);
		if (!re) {
			audiomux.unlock();
			//msleep(1);
			continue;
		}
		//一次send多次 recv
		while (!isExit) {
			AVFrame *frame = decode->Recv();
			if (!frame) {
				break;
			}

			//减去缓冲中为播放的时间
			pts = decode->pts - ap->GetNoPlayMs();
			//重采样
			int size = res->Resample(frame, pcm);
			//播放音频
			while (!isExit) {
				if (size <= 0) {
					qDebug() << "incorrect size";
					break;
				}
				//缓冲未播完，空间不够
				if (ap->GetFree() < size || Pause) {
					//msleep(1);
					continue;
				}
				ap->Write(pcm, size);
				break;
			}
		}
		audiomux.unlock();
	}
	delete pcm;
}

XAudioThread::XAudioThread()
{
	if (!res) {
		qDebug() << "create XResample";
		res = new XResample();
	}
	if (!ap) {
		qDebug() << "create XAduioPlay";
		ap = XAudioPlay::Get();
	}
}

XAudioThread::~XAudioThread()
{
	//等待线程退出
	isExit = true;
	wait();
}

void XAudioThread::SetPause(bool isPause)
{
	this->Pause = isPause;
	if (ap) {
		ap->SetPause(isPause);
	}
}
